using System;
using TokenStream = Lucene.Net.Analysis.TokenStream;
using Query = Lucene.Net.Search.Query;
using TermQuery = Lucene.Net.Search.TermQuery;
using PhraseQuery = Lucene.Net.Search.PhraseQuery;
using BooleanQuery = Lucene.Net.Search.BooleanQuery;
using Term = Lucene.Net.Index.Term;
using Analyzer = Lucene.Net.Analysis.Analyzer;

namespace Lucene.Net.QueryParsers
{
    public class BlankAndQueryParser : QueryParser
    {
        public BlankAndQueryParser(string field, Analyzer analyzer)
            : base(field, analyzer)
        {
        }

        protected internal override Query GetFieldQuery(String field, String queryText)
        {
            TokenStream source = analyzer.TokenStream(field, new System.IO.StringReader(queryText));
            System.Collections.ArrayList v = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
            Lucene.Net.Analysis.Token t;

            while (true)
            {
                try
                {
                    t = source.Next();
                }
                catch (System.IO.IOException e)
                {
                    t = null;
                }
                if (t == null)
                    break;
                v.Add(t);
            }
            try
            {
                source.Close();
            }
            catch (System.IO.IOException e)
            {
                // ignore
            }

            if (v.Count == 0)
                return null;
            else if (v.Count == 1)
                return new TermQuery(new Term(field, ((Lucene.Net.Analysis.Token)v[0]).TermText()));
            else
            {
                PhraseQuery q = new PhraseQuery();
                BooleanQuery b = new BooleanQuery();
                q.SetBoost(2048.0f);
                //q.SetSlop(0);
                b.SetBoost(0.001f);
                for (int i = 0; i < v.Count; i++)
                {
                    Lucene.Net.Analysis.Token token = (Lucene.Net.Analysis.Token)v[i];
                    q.Add(new Term(field, token.TermText()));
                    TermQuery tmp = new TermQuery(new Term(field, token.TermText()));

                    //if(! token.Type().Equals("n"))
                    //{
                    tmp.SetBoost(0.01f);
                    //}
                    b.Add(tmp, Lucene.Net.Search.BooleanClause.Occur.MUST);
                }

                BooleanQuery bQuery = new BooleanQuery();
                // combine the queries, neither
                //requiring or prohibiting matches
                bQuery.Add(q, Lucene.Net.Search.BooleanClause.Occur.SHOULD);
                bQuery.Add(b, Lucene.Net.Search.BooleanClause.Occur.SHOULD);

                return bQuery;
            }
        }
    }
}
